package com.czy.owner.widget.takephoto;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Environment;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.czy.owner.utils.MyLog;
import com.czy.owner.utils.PhoneUtils;
import com.czy.owner.utils.StringUtils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

import static com.czy.owner.global.Constants.BASE_FILE_PATH;

/**
 * Created by Administrator on 2017/2/15 0015.//自定义相机
 */
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback {

    private static final String TAG = "CameraSurfaceView";

    private Context mContext;
    private SurfaceHolder holder;
    private Camera mCamera;

    private int mScreenWidth;
    private int mScreenHeight;
    private CameraTopRectView topView;
    private OnTakeSuccessPath onTakeSuccessPath;


    public void setOnTakeSuccessPath(OnTakeSuccessPath onTakeSuccessPath) {
        this.onTakeSuccessPath = onTakeSuccessPath;
    }

    public CameraSurfaceView(Context context) {
        this(context, null);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        getScreenMetrix(context);
        topView = new CameraTopRectView(context, attrs);

        initView();


    }

    //拿到手机屏幕大小
    private void getScreenMetrix(Context context) {
        WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        WM.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;
        mScreenHeight = outMetrics.heightPixels;

    }

    private void initView() {
        holder = getHolder();//获得surfaceHolder引用
        holder.addCallback(this);
//        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.i(TAG, "surfaceCreated");
        if (mCamera == null) {
            mCamera = Camera.open();//开启相机
            try {
                mCamera.setPreviewDisplay(holder);//摄像头画面显示在Surface上
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.i(TAG, "surfaceChanged");

        setCameraParams(mCamera, mScreenWidth, mScreenHeight);
        mCamera.startPreview();
//        mCamera.takePicture(null, null, jpeg);

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i(TAG, "surfaceDestroyed");
        mCamera.stopPreview();//停止预览
        mCamera.release();//释放相机资源
        mCamera = null;
        holder = null;
    }

    @Override
    public void onAutoFocus(boolean success, Camera Camera) {
        if (success) {
            Log.i(TAG, "onAutoFocus success=" + success);
            System.out.println(success);
        }
    }


    private void setCameraParams(Camera camera, int width, int height) {
        Log.i(TAG, "setCameraParams  width=" + width + "  height=" + height);
        Camera.Parameters parameters = mCamera.getParameters();
        // 获取摄像头支持的PictureSize列表
        List<Camera.Size> pictureSizeList = parameters.getSupportedPictureSizes();
        for (Camera.Size size : pictureSizeList) {
            Log.i(TAG, "pictureSizeList size.width=" + size.width + "  size.height=" + size.height);
        }
        /**从列表中选取合适的分辨率*/
        Camera.Size picSize = getProperSize(pictureSizeList, ((float) height / width));
        if (null == picSize) {
            Log.i(TAG, "null == picSize");
            picSize = parameters.getPictureSize();
        }
        Log.i(TAG, "picSize.width=" + picSize.width + "  picSize.height=" + picSize.height);
        // 根据选出的PictureSize重新设置SurfaceView大小
        float w = picSize.width;
        float h = picSize.height;
        parameters.setPictureSize(picSize.width, picSize.height);
        this.setLayoutParams(new FrameLayout.LayoutParams((int) (height * (h / w)), height));

        // 获取摄像头支持的PreviewSize列表
        List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();

        for (Camera.Size size : previewSizeList) {
            Log.i(TAG, "previewSizeList size.width=" + size.width + "  size.height=" + size.height);
        }
        Camera.Size preSize = getProperSize(previewSizeList, ((float) height) / width);
        if (null != preSize) {
            Log.i(TAG, "preSize.width=" + preSize.width + "  preSize.height=" + preSize.height);
            parameters.setPreviewSize(preSize.width, preSize.height);
        }

        parameters.setJpegQuality(100); // 设置照片质量
        if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 连续对焦模式
        }

        mCamera.cancelAutoFocus();//自动对焦。
        mCamera.setDisplayOrientation(90);// 设置PreviewDisplay的方向，效果就是将捕获的画面旋转多少度显示
        mCamera.setParameters(parameters);

    }

    /**
     * 从列表中选取合适的分辨率
     * 默认w:h = 4:3
     * <p>注意：这里的w对应屏幕的height
     * h对应屏幕的width<p/>
     */
    private Camera.Size getProperSize(List<Camera.Size> pictureSizeList, float screenRatio) {
        Log.i(TAG, "screenRatio=" + screenRatio);
        Camera.Size result = null;
        for (Camera.Size size : pictureSizeList) {
            float currentRatio = ((float) size.width) / size.height;
            if (currentRatio - screenRatio == 0) {
                result = size;
                break;
            }
        }

        if (null == result) {
//            for (Camera.Size size : pictureSizeList) {
//                float curRatio = ((float) size.width) / size.height;
//                if (curRatio == 4f / 3) {// 默认w:h = 4:3
//                    result = size;
//                    break;
//                }
//            }
            float curRatio, deltaRatio;
            float deltaRatioMin = Float.MAX_VALUE;
            for (Camera.Size size : pictureSizeList) {
                curRatio = ((float) size.width) / size.height;
                deltaRatio = Math.abs(screenRatio - curRatio);
                if (deltaRatio < deltaRatioMin) {
                    deltaRatioMin = deltaRatio;
                    result = size;
                }
            }
        }

        return result;
    }


    // 拍照瞬间调用
    private Camera.ShutterCallback shutter = new Camera.ShutterCallback() {
        @Override
        public void onShutter() {
            Log.i(TAG, "shutter");
            System.out.println("执行了吗+1");
        }
    };

    // 获得没有压缩过的图片数据
    private Camera.PictureCallback raw = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera Camera) {
            Log.i(TAG, "raw");
            System.out.println("执行了吗+2");
        }
    };

    //创建jpeg图片回调数据对象
    private Camera.PictureCallback jpeg = new Camera.PictureCallback() {

        private Bitmap bitmap;

        @Override
        public void onPictureTaken(byte[] data, Camera Camera) {


            topView.draw(new Canvas());
            if (onTakeSuccessPath != null) {
                onTakeSuccessPath.onStart();
            }
            Flowable.just(data)
                    .subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .map(new Function<byte[], String>() {
                        @Override
                        public String apply(byte[] data) throws Exception {
                            BufferedOutputStream bos = null;
                            Bitmap bm;
                            bm = BitmapFactory.decodeByteArray(data, 0, data.length);
                            try {
                                // 获得图片
                                String filePath = BASE_FILE_PATH + "/dyk_frame_num_own" + ".jpg";//照片保存路径

                                if (bm == null) {
                                    return "";
                                }
                                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

//                    //图片存储前旋转
                                    Matrix m = new Matrix();
                                    int height = bm.getHeight();
                                    int width = bm.getWidth();
                                    m.setRotate(90);
                                    //旋转后的图片
                                    bitmap = Bitmap.createBitmap(bm, 0, 0, width, height, m, true);

                                    MyLog.e("hep", "执行了吗+3");

                                    File file = new File(filePath);
                                    if (!file.exists()) {
                                        file.createNewFile();
                                    }
                                    bos = new BufferedOutputStream(new FileOutputStream(file));

//                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                                    MyLog.e("hep", "原图尺寸" + bitmap.getHeight() + "----" + bitmap.getWidth());
//                            data.length);
                                    Bitmap sizeBitmap = Bitmap.createScaledBitmap(bitmap,
                                            topView.getViewWidth(), topView.getViewHeight(), true);

                                    bm = Bitmap.createBitmap(sizeBitmap, topView.getRectLeft(),
                                            topView.getRectTop(),
                                            topView.getRectRight() - topView.getRectLeft(),
                                            topView.getRectBottom() - topView.getRectTop());// 截取


                                    bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩到流中

                                } else {

                                    return "1";
                                }
                                return filePath;
                            } catch (Exception e) {
                                e.printStackTrace();
                                MyLog.e("hep", e.getMessage());
                                return "";
                            } finally {
                                try {
                                    bos.flush();//输出
                                    bos.close();//关闭
                                    bm.recycle();// 回收bitmap空间

                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                    }).observeOn(AndroidSchedulers.mainThread())

                    .subscribe(new Consumer<String>() {
                        @Override
                        public void accept(String path) throws
                                Exception {
                            if (StringUtils.isEmpty(path)) {
                                if (onTakeSuccessPath != null)
                                    onTakeSuccessPath.onFail();
                                Toast.makeText(CameraSurfaceView.this.getContext(), "拍照失败", Toast.LENGTH_SHORT).show();
                            } else if ("1".equals(path)) {
                                Toast.makeText(CameraSurfaceView.this.getContext(), "没有检测到内存卡", Toast.LENGTH_SHORT).show();
                                onTakeSuccessPath.onFail();
                            } else {
                                if (onTakeSuccessPath != null)
                                    onTakeSuccessPath.onPath(path);
                            }
//                            mLoadView.CancelLoadView();
                        }
                    });
//            BufferedOutputStream bos = null;
//            Bitmap bm = null;
//            if (data != null) {
//
//
//            }
//
//            try {
//                // 获得图片
//                bm = BitmapFactory.decodeByteArray(data, 0, data.length);
//
//                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//                    String filePath = BASE_FILE_PATH + "/dyk" + System.currentTimeMillis() + ".JPEG";//照片保存路径
//
////                    //图片存储前旋转
//                    Matrix m = new Matrix();
//                    int height = bm.getHeight();
//                    int width = bm.getWidth();
//                    m.setRotate(90);
//                    //旋转后的图片
//                    bitmap = Bitmap.createBitmap(bm, 0, 0, width, height, m, true);
//
//
//                    System.out.println("执行了吗+3");
//                    File file = new File(filePath);
//                    if (!file.exists()) {
//                        file.createNewFile();
//                    }
//                    bos = new BufferedOutputStream(new FileOutputStream(file));
//
////                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
////                            data.length);
//                    Bitmap sizeBitmap = Bitmap.createScaledBitmap(bitmap,
//                            topView.getViewWidth(), topView.getViewHeight(), true);
//                    bm = Bitmap.createBitmap(sizeBitmap, topView.getRectLeft(),
//                            topView.getRectTop(),
//                            topView.getRectRight() - topView.getRectLeft(),
//                            topView.getRectBottom() - topView.getRectTop());// 截取
//
//
//                    bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩到流中
//
//                    if (onTakeSuccessPath != null && !StringUtils.isEmpty(filePath)) {
//
//                        onTakeSuccessPath.onPath(filePath);
//
//
//                    }
//                } else {
//                    Toast.makeText(mContext, "没有检测到内存卡", Toast.LENGTH_SHORT).show();
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//                MyLog.e("yang", e.getMessage());
//            } finally {
//                try {
//                    bos.flush();//输出
//                    bos.close();//关闭
//                    bm.recycle();// 回收bitmap空间
//                    mCamera.stopPreview();// 关闭预览
//                    mCamera.startPreview();// 开启预览
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
            mCamera.stopPreview();// 关闭预览
            mCamera.startPreview();// 开启预览
        }
    };

    public void takePicture() {
        //设置参数,并拍照
        setCameraParams(mCamera, mScreenWidth, mScreenHeight);
        // 当调用camera.takePiture方法后，camera关闭了预览，这时需要调用startPreview()来重新开启预览
        mCamera.takePicture(null, null, jpeg);
    }

//    public void setAutoFocus(){
//        mCamera.autoFocus(this);
//    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    public interface OnTakeSuccessPath {
        void onPath(String path);

        void onFail();

        void onStart();
    }
}
